package com.wwj.tem.controller;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wwj.tem.common.Result;
import com.wwj.tem.config.TemConfig;
import com.wwj.tem.constant.Constants;
import com.wwj.tem.model.entity.SysUser;
import com.wwj.tem.service.impl.SysUserServiceImpl;
import com.wwj.tem.utils.CreateImageCode;
import com.wwj.tem.utils.RedisUtils;
import com.wwj.tem.utils.StringUtils;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author: wwj
 * @create: 2024/7/24 - 23:34
 * Description:
 */
@RestController
@RequestMapping("/acc")
@Api(tags = "登录接口")
public class LoginController {
	
	@Resource
	private SysUserServiceImpl sysUserService;
	
	@Resource
	private TemConfig temConfig;
	
	/**
	 * http://localhost:8080/dev-api/acc/domain?account=admin&password=123456&checkCode=12345
	 * 登录接口
	 * @param account
	 * @param password
	 * @return
	 */
	@RequestMapping("/domain")
	public Result domain(HttpSession session, String account, String password, String checkCode) {
		// 验证码参数校验
		if (StringUtils.isEmpty(checkCode)) {
			return Result.error("验证码不能为空");
		}
		// 验证码校验
		String verifyCode = (String) session.getAttribute(Constants.CHECK_CODE);
		if (StringUtils.isEmpty(verifyCode) || !verifyCode.equalsIgnoreCase(checkCode)) {
			return Result.error("验证码错误");
		}
		LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(SysUser::getUserAccount, account);
		SysUser sysUser = sysUserService.getOne(wrapper);
		if (StringUtils.isNotNull(sysUser)) {
			// 检查账号是否被封禁
			StpUtil.checkDisable(sysUser.getUserId());
			String md5BySalt = SaSecureUtil.md5BySalt(password, temConfig.getKey());
			if (sysUser.getUserPassword().equals(md5BySalt)) {
				StpUtil.login(sysUser.getUserId());
				return Result.ok();
			}
		}
		return Result.error("用户名或密码错误");
	}
	
	/**
	 * http://localhost:8080/dev-api/acc/register?account=admin&password=123456&email=123@qq.com&checkCodeEmail=12345
	 * 注册账号
	 *
	 * @param account  账号
	 * @param password 密码
	 * @param email    邮箱
	 * @param checkCodeEmail 邮箱验证码
	 * @return
	 */
	@RequestMapping("/register")
	public Result register(String account, String password, String email, String checkCodeEmail) {
		// 验证码校验
		if (StringUtils.isEmpty(checkCodeEmail)) {
			return Result.error("邮箱验证码不能为空");
		}
		// 邮箱参数校验
		if (StringUtils.checkEmail(email)) {
			return Result.error("邮箱格式错误");
		}
		// 验证码校验
		String verifyCodeEmail = RedisUtils.get(Constants.EMAIL_CODE_REGISTER + email);
		if (StringUtils.isEmpty(verifyCodeEmail) || !verifyCodeEmail.equalsIgnoreCase(checkCodeEmail)) {
			return Result.error("邮箱验证码错误");
		}
		if (StringUtils.isEmpty(account) || StringUtils.isEmpty(password)) {
			return Result.error("账号或密码不能为空!");
		}
		LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(SysUser::getUserAccount, account);
		SysUser sysUser = sysUserService.getOne(wrapper);
		if (StringUtils.isNotNull(sysUser)) {
			return Result.error("账号已被注册");
		}
		SysUser user = new SysUser();
		user.setUserAccount(account);
		user.setUserPassword(SaSecureUtil.md5BySalt(password, temConfig.getKey()));
		user.setNickName(account);
		user.setEmail(email);
		user.setAvatar(temConfig.getAvatar());
		sysUserService.save(user);
		return Result.ok();
	}
	
	/**
	 * http://localhost:8080/dev-api/acc/tokenInfo
	 * 获取当前登录用户的token信息
	 */
	@GetMapping("/tokenInfo")
	public Result tokenInfo() {
		return Result.data(StpUtil.getTokenInfo());
	}
	
	/**
	 * http://localhost:8080/dev-api/acc/logout
	 * 退出登录
	 */
	@GetMapping("/logout")
	public Result logout() {
		StpUtil.logout();
		return Result.ok();
	}
	
	/**
	 * http://localhost:8080/dev-api/acc/checkCode
	 * 图片验证码
	 *
	 * @param response
	 * @throws IOException
	 */
	@GetMapping("/checkCode")
	public void checkCode(HttpServletResponse response, HttpSession session, Integer type) throws IOException {
		CreateImageCode createImageCode = new CreateImageCode(130, 38, 5, 20);
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		String code = createImageCode.getCode();
		if (type == null || type == 0) {
			session.setAttribute(Constants.CHECK_CODE, code);
		} else {
			session.setAttribute(Constants.CHECK_CODE_EMAIL, code);
		}
		createImageCode.write(response.getOutputStream());
	}
	
	/**
	 * 发送邮箱验证码
	 *
	 * @param session
	 * @param email
	 * @param checkCode
	 * @param type      0 注册 1 重置密码
	 * @return
	 */
	@PostMapping("/sendEmailCode")
	public Result sendEmailCode(HttpSession session, String email, String checkCode, Integer type) {
		try {
			if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_EMAIL))) {
				return Result.error("图片验证码不正确");
			}
			sysUserService.sendEmailCode(email, type);
		} finally {
			session.removeAttribute(Constants.CHECK_CODE_EMAIL);
		}
		return Result.ok("发送成功");
	}
}
